﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;

namespace GeneticAlgorithm
{
	class GA
	{
		public static Hashtable ALWT = new Hashtable();	// Weight Data
		public static Hashtable ALPF = new Hashtable();	// Profit Data

		public static Hashtable BNWT = new Hashtable();	// Binary Weight
		public static Hashtable BNPF = new Hashtable();	// Binary Profit

		public static Hashtable FTNS = new Hashtable(); // Fitness Result
		public static Hashtable BSFT = new Hashtable(); // Best Fitness
		public static Hashtable RLTT = new Hashtable();	// Roulette Wheel Radio

		public static Hashtable PIDX = new Hashtable(); // Population Index

		static void Main( string[] args )
		{
			Queue Qu = new Queue();

			Chromosome.CreateGenomes();

			//적합도 평가
			Fitness();

			while ( true )
			{
				// 적합도 비율 계산
				Selection.EvaluateFitnessRadio( FTNS );
				Selection.EvaluateBestFitness( FTNS );

				for ( int i = 0; i < Define.PLSZ; i++ )
				{
					PIDX.Add( i, Selection.RouletteWheelSelection( i, BSFT ).ToString() );
				}

				Crossover.UniformCrossover( PIDX );
				Mutation.Process( PIDX );

				if ( Evaluate.EvaluateFitness( PIDX ) )
				{
					Print( "Output", true, PIDX );
					break;
				}
			}
		}		
		
		// 적합도 결정 (무게/가치)
		// <Result>: FTNS Hashtable에 순차적으로 저장
		public static void Fitness()
		{
			int	skey = 0;
			IDictionaryEnumerator WT = ALWT.GetEnumerator();
			IDictionaryEnumerator PF = ALPF.GetEnumerator();

			while ( WT.MoveNext() )
			{
				PF.MoveNext();
				double temp = 0.0;
				
				double alwt = double.Parse( string.Format( "{0}", WT.Value ) );
				double alpf = double.Parse( string.Format( "{0}", PF.Value ) );
				temp = alwt / alpf;

				FTNS.Add( skey, temp.ToString() );

				skey++;
			}
		}

		// Hashtable의 저장된 데이터 출력
		// Info: 함께 출력할 String
		// B   : 한 라인에 10개씩 출력, 아니면 1개씩 출력
		// AL  : Hashtable의 변수
		public static void Print( String info, Boolean B, Hashtable AL ) 
		{
			int cnt = 0;
			IDictionaryEnumerator EM = AL.GetEnumerator();
			Console.WriteLine( "---" + info + "---" );

			System.IO.StreamWriter SVFL = new System.IO.StreamWriter( @"output.txt" );


			while ( EM.MoveNext() )
			{
				cnt++;
				Console.Write( "{0}  ", EM.Value );

				if ( B == true )
				{
					SVFL.WriteLine(EM.Value);
					Console.WriteLine();
				}
				else if ( cnt % 10 == 0 )
					Console.WriteLine();
			}

			SVFL.Close();
			SVFL.Dispose();
			Console.WriteLine();
		}
	}
	
}
